/*******************************************************************
 *
 * Copyright (C), 2021-2022, LS, All rights reserved.
 *
 * Author      : 
 * Create Time : 2020-12-15
 * Version     : v0.1
 * Description : 
 *******************************************************************/
 
/*----------------------------Head file----------------------------*/
#include "string.h"
#include "sys_task.h"
#include "bsp_hw_config.h"
#include "ls_ble_adpter.h"
#include "ls_ble_sdk_config.h"
#include "ls_ble_file_text_api.h"

#if (LS_BLE_FILE_SVC_ENABLE)

#define BLE_FILE_TXT_LOG_EN  1
#if BLE_FILE_TXT_LOG_EN
#include "ls_ble_log.h"
#define TAG                             "ble_file_txt"
#define BLE_FILE_TXT_LOG(level, ...)    LS_BLE_LOG_PRINT(level, TAG, __VA_ARGS__)
#else
#define BLE_FILE_TXT_LOG(...)
#endif

/*----------------------------macro file---------------------------*/
#define ONE_CHAR_BYTE_NUM       32

#define file_txt_flash_erase_sector(addr)    ls_ble_adpter_flash_erase_sector(addr)
#define file_txt_flash_write				 ls_ble_adpter_flash_write
#define file_txt_flash_read                  ls_ble_adpter_flash_read

/*----------------------------type define--------------------------*/

/*----------------------------var define---------------------------*/							
static text_info_t text_info;
static bool same_txt = false;

/*-------------------------func declaration------------------------*/

/*-----------------------------------------------------------------*/

void file_text_image_clear(void)
{
    file_txt_flash_erase_sector(FILE_TXT_SAVE_ADDR);
}


static void file_text_image_transport(void)
{
    text_info_t info;
    uint8_t buf[ONE_CHAR_BYTE_NUM];

    file_txt_flash_erase_sector(FILE_TXT_SAVE_ADDR);
    file_txt_flash_read(FILE_TXT_TMP_ADDR, (uint8_t*)&info, sizeof(info));
    file_txt_flash_write(FILE_TXT_SAVE_ADDR, (uint8_t*)&info, sizeof(info));
    
    uint32_t offset = sizeof(info);
    for(int i=0;i<text_info.head.char_num;i++) {
        file_txt_flash_read(FILE_TXT_TMP_ADDR + offset + i*ONE_CHAR_BYTE_NUM, buf, ONE_CHAR_BYTE_NUM);
        file_txt_flash_write(FILE_TXT_SAVE_ADDR + offset + i*ONE_CHAR_BYTE_NUM, buf, ONE_CHAR_BYTE_NUM);
    }
}


bool file_text_image_check_crc_valid(void)
{
    uint16_t crc = 0;
    text_info_t info;
    uint8_t buf[ONE_CHAR_BYTE_NUM];

    file_txt_flash_read(FILE_TXT_SAVE_ADDR, (uint8_t*)&info, sizeof(info));
    if(info.head.char_num > TEXT_CHAR_MAX_NUM)
        return false;

    for(int i=0;i<info.head.char_num;i++) {
        file_txt_flash_read(FILE_TXT_SAVE_ADDR + i*ONE_CHAR_BYTE_NUM + sizeof(info), buf, ONE_CHAR_BYTE_NUM);
        for(int j=0;j<ONE_CHAR_BYTE_NUM;j++) {
            crc += buf[j];
        }
    }

    LS_BLE_LOG_RAW_INFO("CalcCRC=%x, ImgCRC=%x\r\n", crc, info.head.file_crc);
    if(crc != info.head.file_crc) {
        return false;
    }

    return true;
}


bool file_text_is_same(text_info_t *dl)
{
    //TODO: test
    text_info_t local;
    uint8_t same_cnt = 0;

    file_txt_flash_read(FILE_TXT_SAVE_ADDR, (uint8_t*)&local, sizeof(local));
    
    if(dl->head.char_num == local.head.char_num) {
        for(uint8_t i=0;i<local.head.char_num;i++) {
            if(dl->unicode[i] == local.unicode[i]) {
                same_cnt++;
            }
        }
        
        if(same_cnt >= local.head.char_num)
            return true;
        else
            return false;
    }
    else {
        return false;
    }
}


uint8_t ls_ble_file_set_text_info(uint8_t *payload, uint16_t payload_len, file_trans_t* file_trans)
{
    if(payload_len < sizeof(text_head_info_t)) {
        LS_BLE_LOG_RAW_INFO("payload_len err.\n");
        return TXT_INFO_TYPE_ERROR;
    }
    
    //uint8_t err_code = BLE_FILE_SUCCESS;
    text_info_t* info = (text_info_t*)payload;
    LS_BLE_LOG_RAW_INFO("file_len: %d.\n", info->head.file_len);
    LS_BLE_LOG_RAW_INFO("file_crc: %x.\n", info->head.file_crc);
    LS_BLE_LOG_RAW_INFO("scene_type: %d.\n", info->head.scene_type);
    LS_BLE_LOG_RAW_INFO("text_width: %d.\n", info->head.font_width);
    LS_BLE_LOG_RAW_INFO("text_height: %d.\n", info->head.font_height);
    LS_BLE_LOG_RAW_INFO("char_num: %d.\n", info->head.char_num);
    if(info->head.char_num <= CHAR_NUM_MAX_SIZE) {
        for(uint8_t i=0;i<info->head.char_num;i++) {
            LS_BLE_LOG_RAW_INFO("unicode: %x.\n", info->unicode[i]);
        }
    }
    
    if(info->head.file_len <= 0 || info->head.file_len != info->head.char_num*ONE_CHAR_BYTE_NUM || info->head.file_len > FILE_TXT_MAX_SIZE) {
        return TXT_INFO_SIZE_ERROR;
    }
    
    if(info->head.char_num > CHAR_NUM_MAX_SIZE) {
        return TXT_INFO_SIZE_ERROR;
    }
    
    if(info->head.scene_type != 0 || info->head.font_width != FONT_WIDTH || info->head.font_height != FONT_HEIGHT) {
        return TXT_INFO_TYPE_ERROR;
    }
    
    same_txt = file_text_is_same(info);
    if(true == same_txt) {
        LS_BLE_LOG_RAW_INFO("same_txt.\n");
        return 0 ;
    }
    
    memset(&text_info, 0, sizeof(text_info));
    memcpy(&text_info, (uint8_t*)&info->head, sizeof(text_info));
    file_trans->running = true;
    file_txt_flash_erase_sector(FILE_TXT_TMP_ADDR);
    file_txt_flash_write(FILE_TXT_TMP_ADDR, (uint8_t*)&text_info, sizeof(text_info));
    file_trans->offset = sizeof(text_info);
    file_trans->file_type = FILE_TYPE_TEXT;
    
    return 0;
}


void ls_ble_file_text_rx_raw_data_handle(uint8_t *file_data, uint16_t data_len, file_trans_t* file_trans)
{
    if(FILE_TYPE_TEXT != file_trans->file_type)
        return;
    
    if(true == same_txt)
        return;

    file_txt_flash_write(FILE_TXT_TMP_ADDR + file_trans->offset, file_data, data_len);
    file_trans->offset += data_len;
    LS_BLE_LOG_RAW_INFO("rx_raw_data_handle");
}


uint8_t ls_ble_file_text_trans_done_handle(file_trans_t* file_trans)
{
    if(true == same_txt) {
        return FILE_DONE_SUCCESS;
    }

    if(FILE_TYPE_TEXT != file_trans->file_type)
        return 0xFF;

    if(text_info.head.file_len != (file_trans->offset - sizeof(text_info)))
        return FILE_DONE_SIZE_ERR;
    
    //TODO: check crc and move image to right addr
    uint8_t try = 0;
    for(try=0;try<3;try++) {
        file_text_image_transport();
        if(true == file_text_image_check_crc_valid())
            break;
    }
    if(try >= 3) {
        LS_BLE_LOG_RAW_INFO("file text crc check fail");
        return FILE_DONE_CRC_ERR;
    }
    else {
        sys_task_msg_send(MSG_TYPE_UI, UI_EVT_USER_NAME);
    }
    
    LS_BLE_LOG_RAW_INFO("FILE_DONE_SUCCESS");
    return FILE_DONE_SUCCESS;
}

#endif
